#ifndef _GLOBAL_H_
#define _GLOBAL_H_

#define MEDIA_AV_SYNC //modify in menuconfig, CONFIG_MEDIA_AV_SYNC defined in menuconfig
//#define MEDIA_AV_SYNC_WITH_NUM

#ifndef CONFIG_MEDIA_EMULATE_ON_PC
#define MEDIA_USE_EDMA
#endif

#define MEDIA_FS_4BYTES_ALIGN_BUG_FIX
#define MEDIA_SKIP_NOT_HW_RESET

//CONFIG_MEDIA_SAVE_DEMUX_FILES define in menuconfig
//CONFIG_MEDIA_SAVE_DECODE_FILES define in menuconfig


#ifdef CONFIG_MEDIA_EMULATE_ON_PC
/* DAT buffer */
#define DATBUF_MAX_BUF_CNT 20
#define DATBUF_MAX_BUF_LEN 0x80000//0x40000 // 256K
/* 256K for each bit buffer, 4M total ddr */
#define CV_BITBUFS_CONT                 32
#define CV_BITBUFS_SIZE                 0x200000//0x80000//0x40000

/* <2.5M for each buffer */
# define CV_REFBUFS_CONT                6
# define CV_REFBUF_SIZE                 0x2B0000
# define CV_FRAMEBUF_MAX_CONT           5
# define CV_FRAMEBUF_MIN_SIZE           0x180000

#define uswap_64(a) (((a) & 0xFF00000000000000ull) >> 56 | (((a) & 0x00FF000000000000ull) >> 40) \
			| (((a) & 0x0000FF0000000000ull) >> 24) | (((a) & 0x000000FF00000000ull) >> 8) \
			| (((a) & 0x00000000FF000000ull) << 8) | (((a) & 0x0000000000FF0000ull) << 24) \
			| (((a) & 0x000000000000FF00ull) << 40) | ((a) << 56))
#endif
#define ADTS_HEADER_SIZE 7

enum {
	H264_NAL_SLICE           = 1,
	H264_NAL_IDR_SLICE       = 5,
	H264_NAL_SPS             = 7,
	H264_NAL_PPS             = 8,
};

typedef struct {
	uint64_t last_second;
	uint32_t last_ms;
	uint32_t last_tick;
} media_time_t;

typedef struct
{
	uint32_t pkt_num;
	uint32_t pts;
} media_pkt_sync_t; // media av-sync info in packet

typedef enum {
	PREVIEW_PACKET,
	READ_PACKET,
	PREVIEW_FIRST_SLICE,
	READ_FIRST_SLICE,
	PREVIEW_OTHER_CLICE,
	READ_OTHER_CLICE,
	READ_CLICE_PURE,
	SKIP_PACKET
} media_read_opt_t;

typedef enum
{
	GET_PACKET_LEN,
	GET_PACKET_DATA,
	GET_FIRST_SLICE_LEN,
	GET_FIRST_SLICE_DATA,
	GET_OTHER_CLICE_LEN,
	GET_OTHER_CLICE_DATA,
	GET_CLICE_PURE_DATA
} media_bsf_opt_t;

typedef struct
{
	unsigned char sps_seen;
	unsigned char pps_seen;
	unsigned char new_idr;
	int got_irap;
	uint32_t nallen;	// nal unit length
	uint32_t total_len; // remain packet length
} nalustate_t;

typedef struct
{
	int channel;
	unsigned int sample_rate;
	unsigned int sample_size;
} aacconfig_t;

typedef struct
{
	char *metadata;
	int metadata_len;
	unsigned char sps_seen, pps_seen, new_idr, length_size;
	int mkv_block_len_flag;
} videoconfig_t;

extern int media_io_write_packet(void *h, media_bsf_opt_t opt, void *state, phys_addr_t outbuf, int32_t *olen, phys_addr_t inbuf, int32_t ilen);
extern int32_t media_adts_aac_write_packet(void *h, media_bsf_opt_t opt, void *state, phys_addr_t outbuf, int32_t *olen, phys_addr_t inbuf, int32_t ilen);
extern int media_mpeg4_to_m4v(void *h, media_bsf_opt_t opt, void *state, phys_addr_t outbuf, int32_t *olen, phys_addr_t inbuf, int32_t ilen);
extern int32_t media_bsf_h264toannexb(void *h, media_bsf_opt_t opt, void *state, phys_addr_t outbuf, int32_t *olen, phys_addr_t inbuf, int32_t ilen);
extern int32_t media_bsf_hevctoannexb(void *h, media_bsf_opt_t opt, void *state, phys_addr_t outbuf, int32_t *olen, phys_addr_t inbuf, int32_t ilen);
extern int media_get_ms_diff(uint32_t before);
extern int media_flush_time(media_time_t *time, media_time_t *sys_time);
#ifdef CONFIG_MEDIA_EMULATE_ON_PC
extern  uint32_t media_SysGetMs(void);
extern int media_get_ms_from_systime(media_time_t *time, media_time_t *sys_time);
extern uint32_t xthal_get_ccount(void);
#else
extern inline uint32_t media_SysGetMs(void);
#endif

#endif
